﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using Fcdbas.Core.Net ;
using FileTransferProtocol;
using Fcdbas.Core.Util ;
using System.Threading ;

namespace FileTransferClient
{
    
    class FileTransferClient :  BaseSocketService
    {
        protected TransferHead Transfer;
        protected object LockStartProcess = new object();
        public bool Stop = false;
        protected Dictionary<string, FileBlock> ComplatedDic = new Dictionary<string, FileBlock>();
        protected Dictionary<long, ISocketConnection> Connections = new Dictionary<long, ISocketConnection>();
        public TransferHead TransferFile
        {
            get{
                return Transfer;
            }
            set
            {
                Transfer = value;
            }
        }
       
        
        
        #region Fields
        /// <summary>
        /// 一个区块完成时发生
        /// </summary>
        public event BlockFinishedEventHandler BlockFinished;
        /// <summary>
        /// 全部完成时发生
        /// </summary>
        public event AllFinishedEventHandler AllFinished;
        /// <summary>
        /// 连接中断时发生
        /// </summary>
        public event EventHandler ConnectLost;
        public event TransferEventHandler TransferSum;
        /// <summary>
        /// 出现错误时发生
        /// </summary>
        public event FileTransmissionErrorOccurEventHandler ErrorOccurred;
        protected OnEventDelegate FOnEventDelegate;
        protected bool _IsAlive;
        /// <summary>
        /// 获取一个值,该值指示传输是否正在进行
        /// </summary>
        public bool IsAlive { get { return _IsAlive; } }
        protected DateTime _StartTime;
        /// <summary>
        /// 获取传输开始的时间
        /// </summary>
        public DateTime StartTime { get { return _StartTime; } }
        /// <summary>
        /// 获取已用时
        /// </summary>
        public TimeSpan TimePast { get { return DateTime.Now - _StartTime; } }
        /// <summary>
        /// 获取估计剩余时间
        /// </summary>
        public  TimeSpan TimeRemaining 
        { 
            get
            {
                long remainsize = Transfer.FileInfo.FileSize - ComplatedSize;
                double remainM = remainsize / ByteAverSpeed;
                TimeSpan ts = new TimeSpan((long)remainM * 100000);
                return ts;
            }
        }
      
        /// <summary>
        /// 获得已经完成的大小
        /// </summary>
        public long ComplatedSize
        {
            get
            {
                bool isFinished = true;
                long completed = 0;
                foreach (FileBlock fb in ComplatedDic.Values)
                {
                    if (!fb.Complated)
                        isFinished = false;
                    completed += fb.TotalSize;
                }
                if (isFinished)
                    return completed;
                completed = 0;
                foreach (FileBlock fb in ComplatedDic.Values)
                {
                    completed += fb.HasTransfer;
                }
                return completed ;
            }
        }
        /// <summary>
        /// 获取平均速率(字节/秒)
        /// </summary>
        public double ByteAverSpeed
        {
            get
            {
                long completed = 0;
                foreach (FileBlock fb in ComplatedDic.Values)
                {
                    completed += fb.HasTransfer;
                }
                completed = completed / 1024;
                return completed / TimePast.TotalSeconds;
            }
        }
        /// <summary>
        /// 获取平均速率(千字节/秒)
        /// </summary>
        public double KByteAverSpeed
        {
            get
            {
                return ByteAverSpeed / 1024;
            }
        }
        
        #endregion

        #region Constructor



        public FileTransferClient(OnEventDelegate eventDelegate, TransferHead head)
        {
            FOnEventDelegate = eventDelegate;
            this.Transfer = head;
            Stop = false;
            _StartTime = DateTime.Now;
            foreach (FileBlock fb in head.Blocks)
            {
                ComplatedDic.Add(fb.BlockId,new FileBlock());
            }
        }

        #endregion

        #region Methods

        #region Event
        
        protected virtual void Event(FileBlock eventMessage)
        {

            if (FOnEventDelegate != null)
            {
                FOnEventDelegate(eventMessage);
            }

        }
        protected virtual void OnTransferSum()
        {
            if (this.TransferSum != null)
                this.TransferSum(this, EventArgs.Empty);
        }
        protected virtual void OnAllFinished(string fileName)
        {
            if(this.AllFinished != null)
                AllFinished.Invoke(this, new AllFinishedEventArgs(fileName));
        }
        #endregion

        
       

        #endregion

    }
}
